#include "mat4x4.h"
#include "math.h"
#include <memory>

// Constructors
#include "util/mmgr.h"		// Needs to come in early

using namespace math;

Mat4x4::Mat4x4() 
{
	Identity();
}

Mat4x4:: Mat4x4(	float m11, float m12, float m13, float m14,
					float m21, float m22, float m23, float m24,
					float m31, float m32, float m33, float m34,
					float m41, float m42, float m43, float m44 ):
		MATRIX44(	m11, m12, m13, m14,
					m21, m22, m23, m24,
					m31, m32, m33, m34,
					m41, m42, m43, m44 )
{
}

Mat4x4::Mat4x4(const float* _m) 
{
	for (int i=0; i<16; i++)
		m[i/4][i%4] = _m[i];
}



Mat4x4::Mat4x4(	float _fRoll, float _fPitch, float _fYaw)
{
	//D3DXMatrixRotationYawPitchRoll(this, _fYaw, _fPitch, _fRoll);
}

void Mat4x4::Identity()
{
	//D3DXMatrixIdentity(this);
		_11=1;	 _12=0;	 _13=0;	 _14=0;	
		_21=0;	 _22=1;	 _23=0;	 _24=0;	
		_31=0;	 _32=0;	 _33=1;	 _34=0;	
		_41=0;	 _42=0;	 _43=0;	 _44=1;	

}

// Scale / translate
void Mat4x4::Scale(float _x, float _y, float _z)
{
	//D3DXMatrixScaling(this, _x, _y, _z);
}

void Mat4x4::Translation(float _x, float _y, float _z)
{
	//D3DXMatrixTranslation(this, _x, _y, _z);
}

void Mat4x4::Translation(const Vec3& _vPos)
{
	//D3DXMatrixTranslation(this, _vPos.x, _vPos.y, _vPos.z);
}

// Rotation axis
void Mat4x4::RotateX(float _fDeg)
{
	//D3DXMatrixRotationX(this, _fDeg);
}

void Mat4x4::RotateY(float _fDeg)
{
	//D3DXMatrixRotationY(this, _fDeg);
}

void Mat4x4::RotateZ(float _fDeg)
{
	//D3DXMatrixRotationZ(this, _fDeg);
}

void Mat4x4::RotateAxis(float _fDeg, const Vec3& _vAxis)
{	
	//D3DXMatrixRotationAxis(this, &_vAxis, _fDeg);
}

const float* Mat4x4::Get() const
{
	return &m[0][0];
}

math::Vec3  Mat4x4::Transform(const math::Vec3& _Pos) const
{
    /*D3DXVECTOR4 Result;
    D3DXVec3Transform(&Result,  &_Pos, this);
    return math::Vec3(Result.x, Result.y, Result.z);*/

	return _Pos;
}

Mat4x4		operator *	(const Mat4x4 &A, const Mat4x4 &B)	
{
	Mat4x4	Out;
//	D3DXMatrixMultiply(&Out, &A, &B);
	return Out;
}


Mat4x4 Mat4x4::operator!()const
// Inverse matrix
{
//	float		fDeterminant;
	Mat4x4		mMat;
//	D3DXMatrixInverse(&mMat, &fDeterminant, this);
	return mMat;
}

Mat4x4 Mat4x4::operator~()const
// Transpose
{
	Mat4x4		mMat;
//	D3DXMatrixTranspose(&mMat, this);
	return mMat;
}

Vec3 Mat4x4::GetDir() const
{
	return Vec3(_13, _23, _33); 
}

Vec3 Mat4x4::GetRight() const
{
	return Vec3(_11, _21, _31); 
}

Vec3 Mat4x4::GetUp() const
{
	return Vec3(_12, _22, _32); 
}

Vec3 Mat4x4::GetPos() const
{
	return Vec3(_41, _42, _43); 
}

void Mat4x4::SetPos(const Vec3 NewPos)
{
	_41 = NewPos.x;
	_42 = NewPos.y;
	_43 = NewPos.z;
}

// Copy constructors
Mat4x4 Mat4x4::operator=(const Mat4x4		&_A)
{
	_11 = _A._11; _12 = _A._12, _13 = _A._13;  _14 = _A._14; 
	_21 = _A._21; _22 = _A._22, _23 = _A._23;  _24 = _A._24; 
	_31 = _A._31; _32 = _A._32, _33 = _A._33;  _34 = _A._34; 
	_41 = _A._41; _42 = _A._42, _43 = _A._43;  _44 = _A._44; 

	return *this;
}

